﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "CmdOpenFile.h"
#include "CommandIds.h"
#include "CommandRegister.h"
#include "IAction.h"
#include "IApplication.h"
#include "IMainWindow.h"
#include "IUiDocumentViewManager.h"
#include "IUiDocument.h"
#include "IDocument.h"
#include "IDocumentManager.h"
#include "IModelView.h"
#include "UiCommonDialog.h"
#include "GbmpFileSystem.h"
#include "IUiView.h"
#include "IFileExtensions.h"
#include "JournalUtils.h"
#include "FilePath.h"

#include "CommandParameters.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 


using namespace gcmp;
using namespace Sample;

REGISTER_COMMAND(CmdOpenFile)

CmdOpenFile::CmdOpenFile()
    :CommandBase(ID_CMD_OPEN_FILE, true)
{
}

gcmp::OwnerPtr<gcmp::IAction> CmdOpenFile::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    //创建模型文档
    IDocumentManager *pDocumentManager = IDocumentManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDocumentManager, L"获取文档管理器失败", L"GDMP", L"2023-09-30");
    std::wstring filePathName = L"";
    const int nCmdParamsCnt = (int)cmdParams.size();
    if (nCmdParamsCnt != 0 && gcmp::JournalUtils::IsInReplay())
    {
        //回放日志，从CommandParameters解析测试脚本程序集路径
        auto itor = cmdParams.find(L"FilePath");
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(itor != cmdParams.end(), L"回放所需的文件路径不存在", L"GDMP", L"20223-09-30");
        std::wstring path = itor->second.AsWString();
        if (!gcmp::FilePath::IsRelativePath(path))
        {
            // 全路径
            filePathName = path;
        }
        else
        {
            // 相对于当前回放日志的相对路径
            gcmp::FilePath replayJSPath(gcmp::JournalUtils::GetReplayFilePath());
            filePathName = FilePath::Combine(replayJSPath.GetDirectoryName(), path);
        }
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(FileInfo(filePathName).IsFile(), L"打开文件命令在回放时没有找到指定的文件：" + filePathName, L"GDMP", L"2023-09-30");
    }
    else
    {
        //1-指定打开文件
        std::wstring filter = L"Project(*" + IDocumentManager::Get()->GetFileExtensions()->GetDefaultProjectFileExt() + L")";
        std::wstring filePath = gcmp::FileInfo(m_openDir).Exists() ? m_openDir : gcmp::FileSystem::GetWorkingDirPath();
        filePathName = UiCommonDialog::ShowOpenFileDialog(GBMP_TR(L"打开工程"), filePath, filter);
    }

    if (filePathName.empty()) return nullptr;

    m_openDir = gcmp::FilePath(filePathName).GetDirectoryName();

    if (IDocumentManager::Get()->IsFileOpened(filePathName))
    {
        UiCommonDialog::ShowMessageBox(GBMP_TR(L"重复打开文件"), GBMP_TR(L"文件已经被打开过，不能重复打开"), (int)UiCommonDialog::ButtonType::Cancel);
        return nullptr;
    }

    DocumentLoadResult docLoadResult;
    bool interProfessional = false;
    bool restore = false;
    bool savedOrLoaded = true;
    bool bReadOnly = false;
    DocumentLoadOptions docLoadOptions(restore, !savedOrLoaded, bReadOnly, interProfessional);
    std::set<std::wstring> unrecognizedAssemblies;
    IDocument* pDoc = IDocumentManager::Get()->OpenDocument(filePathName, docLoadOptions, docLoadResult, nullptr, &unrecognizedAssemblies);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"打开文档错误", L"GDMP", L"2023-09-30");
    if (pDoc->IsFamilyDocument())
    {
        UiCommonDialog::ShowMessageBox(GBMP_TR(L"打开文件错误"), GBMP_TR(L"不能打开族文件"), (int)UiCommonDialog::ButtonType::Cancel);
        return nullptr;
    }
    PrepareUI(pDoc);

    return nullptr;
}

void CmdOpenFile::PrepareUI(gcmp::IDocument* pDoc)
{
    //创建ui文档
    IMainWindow *pMainWindow = IMainWindow::GetMainWindow();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pMainWindow, L"主窗口获取失败", L"GDMP", L"2023-09-30");
    IUiDocumentViewManager *pDocumentViewManager = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDocumentViewManager, L"文档视图管理器获取失败", L"GDMP", L"2023-09-30");
    IUiDocument* pUiDocument = pDocumentViewManager->CreateUiDocument(pDoc);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocument, L"UI文档创建失败", L"GDMP", L"2023-09-30");
    std::vector<ElementId> modelViewIds = IModelView::GetAllModelViewIds(pDoc);
    DBG_WARN_AND_RETURN_VOID_UNLESS(!modelViewIds.empty(), L"文档中至少有一个视图", L"GDMP", L"2023-09-30");
    IUiView *pUiView = pDocumentViewManager->CreateUiViewWithoutSharingModelView(pUiDocument->GetId(), modelViewIds[0], L"", nullptr);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiView, L"UI视图创建失败", L"GDMP", L"2023-09-30");

    IMainWindow::GetMainWindow()->CreateOrOpenUiView(pUiView->GetUiDocument()->GetId(),
        pUiView->GetModelView()->GetElementId(), false, pUiView->GetTag());

    return;
}